//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:2019/10/08
// @Time:9:58 上午
//
//

#ifndef MQTT_PLUGIN_AUTHPLUGININTERFACE_H
#define MQTT_PLUGIN_AUTHPLUGININTERFACE_H
#include <map>

struct mosquitto;
struct mosquitto_acl_msg;
struct mosquitto_opt;
/**
 * @brief 插件的C++ 封装
 */
class AuthPluginInterface
{
protected:
    std::map<std::string , std::string> m_configMap;
public:
    enum PLUGIN_ERR_TYPE{
        PLUGIN_SUCCESS = 0,
        PLUGIN_AUTH_DENIED = 11, ///< 身份校验失败
        PLUGIN_ACL_DENIED = 12, ///< ACL 检验失败
        PLUGIN_UNKNOWN = 13,
        PLUGIN_DEFER = 17, ///< 插件不处理
    };

    enum ACLTypeEnum{
        ACL_NONE = 0x00 , ///< 为定义
        ACL_READ = 0x01 , ///< 可发送给这个订阅的
        ACL_WRITE = 0x02 , ///< 可发布
        ACL_SUBSCRIBE = 0x04 , ///< 可订阅
        ACL_ALL = 0x07 , ///< 全部控制权
    };

    bool AddConfig(const std::string &key , const std::string &value);
    /**
     * @brief 析构器 显示调用
     */
    virtual ~AuthPluginInterface();
    /**
     * @brief 用于事例化 具体给插件的接口
     * @return 返回接口
     */
    static AuthPluginInterface *New();

    /**
     * @brief 初始化的的时候触发
     */
    virtual void init() = 0 ;

    /**
     * @brief 校验用户 ， 在用户链接上服务器的时候 触发
     * @param username 用户名
     * @param password  用户密码
     * @return PLUGIN_SUCCESS -- 检验成功 ， 可以让用户该用户链接 ， PLUGIN_DEFER -- 调用失败
     */
    virtual int checkUser(const std::string &username  , const std::string &password ) = 0 ;

    /**
     * @brief @brief 客户端身份鉴权
     * @param client
     * @param hint
     * @param identity 客户端提供的身份信息
     * @param key
     * @param max_key_len
     * @return PLUGIN_DEFER -- 插件不支持这个功能 , 不做检查 , PLUGIN_SUCCESS -- 鉴权成功 , PLUGIN_UNKNOWN -- 错误
     */
    virtual int getPskKey(mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len) = 0 ;

    /**
     * @brief 校验 是否有权限这条消息的订阅 / 发布 权限
     * @param client 客户端的上下文
     * @param access 当前消息的类型
     * @param msg 消息体
     * @return PLUGIN_SUCCESS -- 成功 , PLUGIN_ACL_DENIED -- 无权操作 这个 Topic
     */
    virtual int checkAcl(mosquitto *client, ACLTypeEnum access, const mosquitto_acl_msg *msg) = 0 ;

    /**
     * @brief 安全清理 , 关闭 mosquitto 服务器的时候调用 或 要求重新加载 配置文件的时候
     * @param auth_opts
     * @param auth_opts_count
     * @param reload false -- 第一次加载配置文件 ， true -- 非第一次 调用
     * @return PLUGIN_SUCCESS -- 操作成功 , PLUGIN_UNKNOWN -- 操作错误
     */
    virtual int cleanupSecurity(mosquitto_opt *auth_opts, int auth_opts_count, bool reload) = 0 ;
    /**
     * @brief 安全初始化 ，在启动 服务的时候加载
     * @param auth_opts
     * @param auth_opts_count
     * @param reload false -- 第一次加载配置文件 ， true -- 非第一次 调用
     * @return PLUGIN_SUCCESS -- 操作成功 , PLUGIN_UNKNOWN -- 操作错误
     */
    virtual int initSecurity(mosquitto_opt *auth_opts, int auth_opts_count, bool reload) = 0 ;
};


#endif //MQTT_PLUGIN_AUTHPLUGININTERFACE_H
